package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.dto.SetmealDto;
import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.service.SetmealDishService;
import com.itheima.reggie.entity.*;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishService;
import com.itheima.reggie.service.SetmealService;
import com.itheima.reggie.entity.SetmealDish;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * 套餐管理
 * @author jay
 */
@RestController
@RequestMapping("/setmeal")
@Slf4j
@Api(tags = "套餐相关接口")
public class SetmealController {
    @Autowired
    private SetmealService setmealService;
    @Autowired
    private SetmealDishService setmealDishService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private DishService dishService;

    /**
     * 添加套餐
     * @param setmealDto
     * @return
     */
    @PostMapping
    @CacheEvict(value = "setmealCache", allEntries = true)
    @ApiOperation(value = "新增套餐接口")
    public R<String> save(@RequestBody SetmealDto setmealDto){
        log.info("setmealDto = {}", setmealDto);
        setmealService.saveWhitSetmealDish(setmealDto);
        return R.success("套餐添加成功");
    }

    /**
     * 分页查询
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    @ApiOperation(value = "套餐分页查询接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页码", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页记录数", required = true),
            @ApiImplicitParam(name = "name", value = "套餐名称", required = false)
    })
    public R<Page> page(int page,int pageSize,String name){
        log.info("page = {},pageSize = {}, name = {}", page, pageSize, name);
        Page<Setmeal> setmealPage = new Page<>(page, pageSize);
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        //name过滤，根据name like模糊查询
        queryWrapper.like(name != null,Setmeal::getName,name);
        //排序过滤
        queryWrapper.orderByDesc(Setmeal::getUpdateTime);
        //分页
        setmealService.page(setmealPage,queryWrapper);

        //给每条数据赋值套餐菜品Name
        Page<SetmealDto> setmealDtoPage = new Page<>();
        BeanUtils.copyProperties(setmealPage,setmealDtoPage,"records");//对象拷贝,排除records
        //dishDtoPage 需要 records => records == SetmealDto集合
        //            => 需要categoryName => 需要categoryId
        List<Setmeal> records = setmealPage.getRecords(); // 拿出setmealPage的records
        List<SetmealDto> list = new ArrayList<>();// setmealDto的集合
        //1. 获取categoryName
        //2. 获取带有菜品名的records
        //3. 将records传入setmealDtoPage，并传回前端
        for (int i = 0; i < records.size(); i++) {
            Long categoryId = records.get(i).getCategoryId(); //遍历获取categoryId
            if(categoryId == null) continue; //判断菜品是否有分类
            Category category = categoryService.getById(categoryId); //遍历获取category对象
            String categoryName = category.getName(); //遍历获取需要的categoryName
            SetmealDto setmealDto = new SetmealDto(); //创建SetmealDto
            BeanUtils.copyProperties(records.get(i),setmealDto); // 数据拷贝给setmealDto
            setmealDto.setCategoryName(categoryName); //categoryName传入
            list.add(setmealDto);//setmealDto 传入 list
        }
        setmealDtoPage.setRecords(list);//list 传入 setmealDtoPage

        return R.success(setmealDtoPage);
    }

    /**
     * 按id查询SetmealDto
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @ApiOperation(value = "按ID查询套餐Dto接口")
    public R<SetmealDto> getById(@PathVariable Long id){
        log.info("id = {}", id);
        //套餐基本信息查询
        Setmeal setmeal = setmealService.getById(id);
        //套餐分类名字查询
        SetmealDto setmealDto = new SetmealDto();
        BeanUtils.copyProperties(setmeal, setmealDto);
        Category category = categoryService.getById(setmeal.getCategoryId());
        setmealDto.setCategoryName(category.getName());
        //套餐菜品查询
        LambdaQueryWrapper<SetmealDish> setmealDishWrapper = new LambdaQueryWrapper<>();
        setmealDishWrapper.eq(SetmealDish::getSetmealId,id);
        List<SetmealDish> dishList = setmealDishService.list(setmealDishWrapper);
        setmealDto.setSetmealDishes(dishList);
        return R.success(setmealDto);
    }

    /**
     * 修改套餐
     * @param setmealDto
     * @return
     */
    @CacheEvict(value = "setmealCache", key = "#setmealDto.categoryId + '_1'")
    @PutMapping
    @ApiOperation(value = "修改套餐接口")
    public R<String> updateWithSetmealDish(@RequestBody SetmealDto setmealDto){
        log.info("setmealDto = {}",setmealDto);
        setmealService.updateWithSetmealDish(setmealDto);
        return R.success("套餐修改成功");
    }

    /**
     * 按ids删除套餐
     * @param ids
     * @return
     */
    @CacheEvict(value = "setmealCache", allEntries = true)
    @DeleteMapping
    @ApiOperation(value = "删除套餐接口")
    public R<String> deleteByIds(Long[] ids){
        log.info("ids = {}", ids);
        //删除套餐基本信息
        setmealService.removeWithDish(ids);
        return R.success("删除成功");
    }

    /**
     * 修改状态
     * @param ids
     * @return
     */
    @CacheEvict(value = "setmealCache", allEntries = true)
    @PostMapping("/status/{status}")
    @ApiOperation(value = "修改套餐状态接口")
    public R<String> update(Long[] ids,@PathVariable int status){
        log.info("ids = {}, status = {}", ids, status);
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Setmeal::getId,ids); //条件遍历过滤 ids
        List<Setmeal> list = setmealService.list(queryWrapper); //拿出集合赋值status
        for (int i = 0; i < list.size(); i++) {
            list.get(i).setStatus(status);
        }
        setmealService.updateBatchById(list);
        return R.success("状态修改成功");
    }

    /**
     * 根据条件查询对应的套餐
     * @return
     */
    @Cacheable(value = "setmealCache", key = "#setmeal.categoryId + '_1'", unless = "#result == null")
    @GetMapping("/list")
    @ApiOperation(value = "套餐条件查询接口")
    public R<List<Setmeal>> list(Setmeal setmeal){
        log.info("setmeal = {}", setmeal);
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        //条件过滤，categoryId过滤
        queryWrapper.eq(setmeal.getCategoryId() != null, Setmeal::getCategoryId, setmeal.getCategoryId());
        //name过滤
        //queryWrapper.like(setmeal.getName() != null, Setmeal::getName, setmeal.getName());
        //状态过滤
        queryWrapper.eq(setmeal.getStatus() != null, Setmeal::getStatus, setmeal.getStatus());
        //添加排序条件
        queryWrapper.orderByDesc(Setmeal::getUpdateTime);
        List<Setmeal> list = setmealService.list(queryWrapper);
        return R.success(list);
    }

    /**
     * 根据套餐ID查询对应的菜品
     * @param id
     * @return
     */
    @GetMapping("/dish/{id}")
    @ApiOperation(value = "套餐菜品查询接口")
    public R<List<DishDto>> dish(@PathVariable Long id){
        log.info("id = {}", id);
        //查询SetmealDishe集合
        LambdaQueryWrapper<SetmealDish> setmealDishWrapper = new LambdaQueryWrapper<>();
        setmealDishWrapper.eq(id != null, SetmealDish::getSetmealId,id);
        List<SetmealDish> setmealDishes = setmealDishService.list(setmealDishWrapper);

        List<DishDto> dishDtos = new ArrayList<>();
        for (int i = 0; i < setmealDishes.size(); i++) {
            DishDto dishDto = new DishDto();
            //根据id查找dish，并加入到dishDtos集合中
            Dish dish = dishService.getById(setmealDishes.get(i).getDishId());
            BeanUtils.copyProperties(dish,dishDto); //数据拷贝
            dishDto.setCopies(setmealDishes.get(i).getCopies()); //加入copies(份数)
            dishDtos.add(dishDto);
        }
        return R.success(dishDtos);
    }
}
